use std::collections::HashMap;

use async_trait::async_trait;
use mf_state::{Transaction, transaction::Command};
use mf_transform::TransformResult;
use serde::Deserialize;
use serde_json::Value;

#[derive(Debug, Deserialize)]
pub struct InsertCommand {
    pub parent_id: Box<str>,
    pub name: Box<str>,
    pub r#type: String,
    pub other: HashMap<String, Value>,
}
impl InsertCommand {
    pub fn new(
        parent_id: Box<str>,
        name: Box<str>,
        r#type: String,
    ) -> Self {
        Self { parent_id, name, r#type, other: HashMap::new() }
    }
    pub fn add_attr(
        &mut self,
        key: &str,
        value: Value,
    ) {
        self.other.insert(key.to_string(), value);
    }
}

#[async_trait]
impl Command for InsertCommand {
    async fn execute(
        &self,
        tr: &mut Transaction,
    ) -> TransformResult<()> {
        // 根据参数中的parent_id获取目标节点
        if tr.doc().get_node(&self.parent_id).is_none(){
            return Err(anyhow::anyhow!("目标节点不存在".to_string()));
        }

        let factory = tr.schema.factory();
        let nodes = factory.create_tree(&self.r#type, None, Some(&self.other), vec![], None)?;
        tr.add_node(self.parent_id.clone(), vec![nodes])?;
        Ok(())
    }

    fn name(&self) -> String {
        "InsertCommand".to_string()
    }
}
